package uk.co.revisual.domino.proxies
{
		
	import flexunit.framework.Assert;
	
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.IProxy;
	import org.puremvc.as3.multicore.patterns.command.MacroCommand;
	import org.puremvc.as3.multicore.patterns.command.SimpleCommand;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;
	import org.puremvc.as3.multicore.patterns.observer.Notifier;
	import org.puremvc.as3.multicore.patterns.proxy.Proxy;
	import org.puremvc.as3.multicore.utilities.statemachine.State;
	
	import uk.co.revisual.commands.MacroCommandOne;
	import uk.co.revisual.commands.SimpleCommandOne;
	import uk.co.revisual.commands.SimpleCommandTwo;
	import uk.co.revisual.creation.ClassFactory;
	import uk.co.revisual.creation.ClassFactoryTest;
	import uk.co.revisual.creation.DynamicClassFactory;
	import uk.co.revisual.creation.FactoryError;
	import uk.co.revisual.domino.proxies.FSMClassFactoryProxy;
	import uk.co.revisual.domino.proxies.FSMModelProxyTest;
	import uk.co.revisual.states.SubStateOne;
	import uk.co.revisual.states.SubStateTwo;
	
	public class FSMClassFactoryProxyTest
	{	
		
		
		[Test]		
		/**
		 * Tests adding classes via the constructor arguments
		 * Also tests hasClass and create
		 */
		public function testConstructor():void
		{
			var testSubject:IProxy = new FSMClassFactoryProxy( ClassFactory );
			Assert.assertTrue( testSubject.getData() is ClassFactory );			
		}
		
		/**
		 * Tests adding classes via the addClass method
		 * The factory only accepts ICommands and States
		 */
		[Test]
		public function testAddClass():void
		{
			var testSubject:DynamicClassFactory = new FSMClassFactoryProxy( ClassFactory );
			
			Assert.assertTrue( testSubject.addClass( State ) );
			Assert.assertTrue( testSubject.addClass( SubStateOne ) );
			Assert.assertTrue( testSubject.addClass( SubStateTwo ) );
			Assert.assertTrue( testSubject.addClass( [ SimpleCommandOne, SimpleCommandTwo, MacroCommandOne ] ) );
			
			Assert.assertFalse( testSubject.addClass( SubStateTwo ) );
			Assert.assertFalse( testSubject.addClass( [ SimpleCommandOne, SimpleCommandTwo ] ) );
			Assert.assertFalse( testSubject.addClass( [ SimpleCommandOne, MacroCommand ] ) );
			Assert.assertFalse( testSubject.addClass( [ Proxy, Mediator ] ) );
			Assert.assertFalse( testSubject.addClass( [ Notifier, SimpleCommand ] ) );
					
		}
		
		[Test]
		public function testHasClass():void
		{
			var testSubject:DynamicClassFactory = new FSMClassFactoryProxy( ClassFactory );
			
			testSubject.addClass( [	State, 
				SubStateOne, 
				SubStateTwo, 
				SimpleCommandOne, 
				SimpleCommandTwo, 
				MacroCommandOne,
				Proxy, 
				Mediator,
				Notifier, 
				SimpleCommand ] );
			
			Assert.assertTrue( testSubject.hasClass( "org.puremvc.as3.multicore.utilities.statemachine.State" ) );
			Assert.assertTrue( testSubject.hasClass( "uk.co.revisual.states.SubStateOne" ) );
			Assert.assertTrue( testSubject.hasClass( "uk.co.revisual.states.SubStateTwo" ) );
			Assert.assertTrue( testSubject.hasClass( "uk.co.revisual.commands.SimpleCommandOne" ) );
			Assert.assertTrue( testSubject.hasClass( "uk.co.revisual.commands.SimpleCommandTwo" ) );
			Assert.assertTrue( testSubject.hasClass( "uk.co.revisual.commands.MacroCommandOne" ) );
			Assert.assertTrue( testSubject.hasClass( "org.puremvc.as3.multicore.patterns.command.SimpleCommand" ) );
			
			Assert.assertFalse( testSubject.hasClass( "org.puremvc.as3.multicore.patterns.proxy.Proxy" ) );
			Assert.assertFalse( testSubject.hasClass( "org.puremvc.as3.multicore.patterns.mediator.Mediator" ) );
			Assert.assertFalse( testSubject.hasClass( "org.puremvc.as3.multicore.patterns.observer.Notifier" ) );
			Assert.assertFalse( testSubject.hasClass( "org.puremvc.as3.multicore.patterns.command.MacroCommand" ) );
			
		}
		
		[Test]
		public function testCreate():void
		{
			var testSubject:DynamicClassFactory = new FSMClassFactoryProxy( ClassFactory );
			
			testSubject.addClass( [	State, 
									SubStateOne, 
									SubStateTwo, 
									SimpleCommandOne, 
									SimpleCommandTwo, 
									MacroCommandOne,
									Proxy, 
									Mediator,
									Notifier, 
									SimpleCommand ] );
			
			Assert.assertEquals( testSubject.create( "org.puremvc.as3.multicore.utilities.statemachine.State" ), State );
			Assert.assertEquals( testSubject.create( "uk.co.revisual.states.SubStateOne" ), SubStateOne );
			Assert.assertEquals( testSubject.create( "uk.co.revisual.states.SubStateTwo" ), SubStateTwo );
			Assert.assertEquals( testSubject.create( "uk.co.revisual.commands.SimpleCommandOne" ), SimpleCommandOne );
			Assert.assertEquals( testSubject.create( "uk.co.revisual.commands.SimpleCommandTwo" ), SimpleCommandTwo );
			Assert.assertEquals( testSubject.create( "uk.co.revisual.commands.MacroCommandOne" ), MacroCommandOne );
			Assert.assertEquals( testSubject.create( "org.puremvc.as3.multicore.patterns.command.SimpleCommand" ), SimpleCommand );
			
			try{
				testSubject.create( "org.puremvc.as3.multicore.patterns.proxy.Proxy" );
				Assert.fail("No Error thrown for trying to retrieve a class that isn't there");
			}catch(error:FactoryError){
				Assert.assertEquals( error.id, 5100 + FactoryError.CLASSES_NOT_DECLARED );
			}catch(error:Error){
				Assert.fail( "unknown error :: " + error.toString() );
			}
			
		}
	}
}